

#include <stdafx.h>
#include <stdlib.h>
#include <windows.h>
#include <GL/glut.h>
#include "glm.h"
#include "iostream"
using namespace std;


static float ypoz = 0, zpoz = 0;

// You need to declare your self a pointer to the model
// This is where the data will be loaded
GLMmodel* pmodel1 = NULL;
GLMmodel* pmodel2 = NULL;
double dx[100],dy[100],dz[100];
double numberPolygon = 100;
void init(void) 
{
	glClearColor (0.0, 0.0, 0.0, 0.0);   
	glEnable(GL_DEPTH_TEST);
	glShadeModel (GL_SMOOTH);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);
	glPolygonMode(GL_FRONT_AND_BACK, GL_3D_COLOR_TEXTURE);
	for(int i=0;i<numberPolygon; i++)
	{
		dx[i] = rand() % 1000 - 500 ;
		dy[i] = rand() % 1000 - 500 ;
		dz[i] = rand() % 1000 - 500 ;

		dx[i]/= 1000000;
		dy[i]/= 1000000;
		dz[i]/= 1000000;
	}
}

void drawAxis( void ){
	glBegin( GL_LINES );
	glColor3f( 0, 0, 1 );
	glVertex3f( -15, 0 ,0 );
	glVertex3f( 15, 0 ,0 );
	
	glColor3f( 0, 1, 0 );
	glVertex3f( 0, -15 ,0 );
	glVertex3f( 0, 15 ,0 );
	
	glColor3f( 1, 0, 0 );
	glVertex3f( 0, 0 , -15 );
	glVertex3f( 0, 0 , 15 );
	glEnd();
}

void moveToOther()
{
	int check[100000];
	int newPos[100000];
	for(int i=0; i<100000;i++)
		check[i]=-1;

	GLMgroup* group = pmodel1->groups;
	int numberGroup = pmodel1->numgroups;
	for(int i=0; i < numberGroup;i++)
	{
		for(int j=0;j< group->numtriangles;j++)
		{
			int index = group->triangles[j];
			GLMtriangle triangle = pmodel1->triangles[index];
			for(int t = 0 ;t < 3; t++)
			{
				int indexVertices = triangle.vindices[t];
				if (check[indexVertices]==-1){
					check[indexVertices]=1;

					pmodel1->vertices[3*indexVertices]  += dx[i];
					pmodel1->vertices[3*indexVertices+1]+= dy[i];
					pmodel1->vertices[3*indexVertices+2]+= dz[i];
					/*
					if (i < numberGroup/2)
					{
						pmodel1->vertices[3*indexVertices]  += 0;
						pmodel1->vertices[3*indexVertices+1]+= 0;
						pmodel1->vertices[3*indexVertices+2]+= 0;
					}
					else
					{
						pmodel1->vertices[3*indexVertices]  += .001;
						pmodel1->vertices[3*indexVertices+1]+= .001;
						pmodel1->vertices[3*indexVertices+2]+= .001;
					}
					*/
				}
			}
		}
		group = group->next;
	}
}
void moveBall()
{
	int check[100000];
	int newPos[100000];
	for(int i=0; i<100000;i++)
		check[i]=-1;

	GLMgroup* group = pmodel2->groups;
	int numberGroup = pmodel2->numgroups;
	for(int i=0; i < numberGroup;i++)
	{
		for(int j=0;j< group->numtriangles;j++)
		{
			int index = group->triangles[j];
			GLMtriangle triangle = pmodel2->triangles[index];
			for(int t = 0 ;t < 3; t++)
			{
				int indexVertices = triangle.vindices[t];
				if (check[indexVertices]==-1){
					check[indexVertices]=1;

					//pmodel2->vertices[3*indexVertices]  -= 0.01;
					pmodel2->vertices[3*indexVertices+1]+= 0.001;
					//pmodel2->vertices[3*indexVertices+2]-= 0.001;
				}
			}
		}
		group = group->next;
	}
}
void drawmodel_box(void)
{
	// Load the model only if it hasn't been loaded before
	// If it's been loaded then pmodel1 should be a pointer to the model geometry data...otherwise it's null
    if (!pmodel1) 
	{
		// this is the call that actualy reads the OBJ and creates the model object
        pmodel1 = glmReadOBJ("bonglyban1.obj");	
		cout << pmodel1->numvertices <<endl;
		//dividePoint();
        if (!pmodel1) exit(0);
		// This will rescale the object to fit into the unity matrix
		// Depending on your project you might want to keep the original size and positions you had in 3DS Max or GMAX so you may have to comment this.
        glmUnitize(pmodel1);
		// These 2 functions calculate triangle and vertex normals from the geometry data.
		// To be honest I had some problem with very complex models that didn't look to good because of how vertex normals were calculated
		// So if you can export these directly from you modeling tool do it and comment these line
		// 3DS Max can calculate these for you and GLM is perfectly capable of loading them
		//glmScale(pmodel1, 2);
        glmFacetNormals(pmodel1);        
		glmVertexNormals(pmodel1, 90.0);
		cout << pmodel1->numvertices <<endl;
		cout << pmodel1->numgroups;
		//	moveToOther();
    }
	/*
    if (!pmodel2) 
	{
		// this is the call that actualy reads the OBJ and creates the model object
        pmodel2 = glmReadOBJ("bong6.obj");	
		//dividePoint();
        if (!pmodel2) exit(0);
		// This will rescale the object to fit into the unity matrix
		// Depending on your project you might want to keep the original size and positions you had in 3DS Max or GMAX so you may have to comment this.
        glmUnitize(pmodel2);
		// These 2 functions calculate triangle and vertex normals from the geometry data.
		// To be honest I had some problem with very complex models that didn't look to good because of how vertex normals were calculated
		// So if you can export these directly from you modeling tool do it and comment these line
		// 3DS Max can calculate these for you and GLM is perfectly capable of loading them
		//glmScale(pmodel1, 2);
        glmFacetNormals(pmodel2);        
		glmVertexNormals(pmodel2, 90.0);
		//	moveToOther();
    }
	*/
    // This is the call that will actualy draw the model
	// Don't forget to tell it if you want textures or not :))
    //glmDraw(pmodel1, GLM_SMOOTH| GLM_TEXTURE);
	//moveToOther();
	//moveToOther();
	//moveBall();
    glmDraw(pmodel1, GLM_SMOOTH| GLM_MATERIAL);	
   // glmDraw(pmodel2, GLM_SMOOTH| GLM_MATERIAL);	
	drawAxis();
    glutPostRedisplay();
	/*cout << pmodel1->vertices[1] - pmodel2->vertices[1]<<endl;
	cout << pmodel1->vertices[2] - pmodel2->vertices[2]<<endl;
	cout << pmodel1->vertices[3] - pmodel2->vertices[3]<<endl;
	*/
}


void display(void)
{
	
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity ();
	
	glTranslatef(0,0,-5);	
	glPushMatrix();	
	// I added these to be able to rotate the whole scene so you can see the box and textures
		glRotatef(ypoz,0,1,0);
		glRotatef(zpoz,0,0,1);		
		drawmodel_box();
	glPopMatrix();

	Sleep(5);
	glutSwapBuffers();
	
   
}

void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
   glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
	  case 'y':         
		  ypoz=ypoz+5;
		  if (ypoz>360) ypoz=0;
         glutPostRedisplay();
         break;
	 case 'z':         
		 zpoz = zpoz+5;
		 if (zpoz>360) zpoz=0;
         glutPostRedisplay();
         break;	
   }
}

void animate()
{
	ypoz+=0.5;
	if (ypoz>360) ypoz=0;
	glutPostRedisplay();
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   // Do a little animation - rotate the object a bit so we can see it better
   //glutIdleFunc(animate);
   glutMainLoop();
   return 0;
}

